﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WikiQuizz.Common.Entities;
using WikiQuizz.StandardImplementations;
using System.Xml.Linq;
using WikiQuizz.Common.WikiAPIHelper;
using WikiQuizz.Common.Interfaces;
using System.Windows.Forms;
using System.Threading;
using System.Collections;
using WikiQuizz.Common.Utils;
using WikiQuizz.Common.Resource;
using WikiQuizz.Exporter.ExportEntities;

namespace WikiQuizz.Exporter
{
    class Program
    {        
        static void Main(string[] args)
        {
            UpdateSingleItem(1509308);
            //AnalyzeSingleItem("Volksrepublik China");
            return;

            SetUpdateConfiguration();
            Console.WriteLine("Initial download started...");
            ExtractData();
            Console.WriteLine("Initial download finished...");
            Console.ReadLine();
        }

        private static void UpdateSingleItem(int itemId)
        {
            IUpdateManager manager = new UpdateManager();

            manager.UpdateItem(itemId);
        }

        private static void SetUpdateConfiguration()
        {
            UpdateConfigurationEntity update = new UpdateConfigurationEntity();

            update.DaysUntilNextUpdate = 5;

            Workbench.SerializeToFile(update, Strings.UPDATE_FILE);
        }

        private static void ExtractData()
        {            
            ICategoryManager service = new CategoryManager();
            ICountryManager manager = new CountryManager();

            Console.Write("load categories from datastore...");

            ICollection<CategoryEntity> categories = service.Categories;

            Console.WriteLine("done.");

            Console.WriteLine("get category details from wikipedia...");

            var entities = GetCategorieDetails(categories);

            Console.WriteLine("get country details...");

            var completeEntities = GetCountryDetails(entities);

            Console.Write("save countries to datastore...");
            manager.Countries = completeEntities;
            SaveIndividualLists(completeEntities);
            Console.WriteLine("done.");         
        }

        private static void SaveIndividualLists(ICollection<CountryEntity> countries)
        {
            var res = (from o in countries
                      select new PopulationEntity { Title = o.Title, Population = o.Population }).ToList();

            Workbench.SerializeToFile(res, "Population.xml");

            var popDens = (from o in countries
                           select new PopulationDensityEntity { Title = o.Title, PopulationDensity = o.PopulationDensity }).ToList();

            Workbench.SerializeToFile(popDens, "PopulationDensity.xml");

            var lang = (from o in countries
                        select new OfficialLanguageEntity { Title = o.Title, OfficialLanguage = o.OfficialLanguage }).ToList();

            Workbench.SerializeToFile(lang, "OfficialLanguage.xml");

            var area = (from o in countries
                        select new AreaEntity { Title = o.Title, Area = o.Area }).ToList();

            Workbench.SerializeToFile(area, "Area.xml");

            var cap = (from o in countries
                       select new CapitalEntity { Title = o.Title, Capital = o.Capital }).ToList();

            Workbench.SerializeToFile(cap, "Capital.xml");            
        }

        private static ICollection<CountryEntity> GetCategorieDetails(ICollection<CategoryEntity> categories)
        {
            List<CountryEntity> entities = new List<CountryEntity>();

            foreach (var item in categories)
            {
                Console.Write("get category {0}...", item.Title);
                XElement staaten = WikiAPIHelperClass.QueryCategorieMembers(item.Title);

                entities.AddRange((from s in staaten.Descendants(XName.Get("cm"))
                                   select new CountryEntity
                                   {
                                       PageId = Convert.ToInt32(s.Attribute("pageid").Value),
                                   }).ToList<CountryEntity>());

                Console.WriteLine("done.");
                Thread.Sleep(1000);
            }

            return entities;
        }

        private static ICollection<CountryEntity> GetCountryDetails(ICollection<CountryEntity> entities)
        {
            var distinctResult = entities.GroupBy(p => p.PageId).Select(g => g.First()).ToList<CountryEntity>();

            int loopSize = Convert.ToInt32(Math.Round((distinctResult.Count / 50) + 0.5));

            int skip = 0;
            int take = 50;

            List<CountryEntity> completeEntities = new List<CountryEntity>();

            for (int i = 0; i < loopSize; i++)
            {
                Console.Write("get bulk no. {0}...", i);
                var idList = (from o in distinctResult select o.PageId).Distinct<int>().Skip(skip).Take(take).ToList();
                XElement infos = WikiAPIHelperClass.QueryInfo(idList);

                completeEntities.AddRange((from o in infos.Descendants(XName.Get("page"))
                                           select new CountryEntity
                                    {
                                        PageId = Convert.ToInt32(o.Attribute("pageid").Value),
                                        Title = o.Attribute("title").Value,
                                        LastRevId = Convert.ToInt32(o.Attribute("lastrevid").Value),
                                        LastUpdate = DateTime.Now
                                    }).ToList<CountryEntity>());
                skip += take;
                Console.WriteLine("done.");
                Thread.Sleep(1000);
            }

            ICountryManager manager = new CountryManager();

            foreach (var country in completeEntities)
            {
                Console.Write("get country details for {0}...", country.Title);
                var item = WikiAPIHelperClass.GetCountryData(country.Title);
                Workbench.SerializeToFile(item, country.Title + ".XML");
                country.Capital = manager.GetCapital(item);
                country.Population = manager.GetPopulation(item);
                country.PopulationDensity = manager.GetPopulationDensity(item);
                country.Area = manager.GetArea(item);
                country.OfficialLanguage = manager.GetOfficialLanguage(item);
                country.ISO3166 = manager.GetISO3166(item);
                Console.WriteLine("done.");
                Thread.Sleep(1000);                
            }

            return completeEntities;
        }

        private static void AnalyzeSingleItem(string title)
        {
            CountryEntity country = new CountryEntity();
            ICountryManager manager = new CountryManager();
            var item = Workbench.DeSerializeFromFile<XElement>(title + ".XML");
            country.Capital = manager.GetCapital(item);
            country.Population = manager.GetPopulation(item);
            country.PopulationDensity = manager.GetPopulationDensity(item);
            country.Area = manager.GetArea(item);
            country.OfficialLanguage = manager.GetOfficialLanguage(item);
            country.ISO3166 = manager.GetISO3166(item);
            bool test = country.IsValid;
        }
    }
}
